﻿using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.Windows;
using CredentialsManager.Properties;
using MVVMFoundation;

namespace CredentialsManager.Helpers
{
    public static class ErrorHandler
    {
        #region Private methods

        private static bool IsWCFRelatedException(Exception ex)
        {
            if (ex.GetType() == typeof(CommunicationException) ||
                ex.GetType().IsSubclassOf(typeof(CommunicationException)) ||
                ex.GetType() == typeof(TimeoutException) ||
                ex.GetType() == typeof(InvalidOperationException))
            {
                return true;
            }

            return false;
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Displays the standard application error message for WCF network and service-side exceptions
        /// that don't have specific handling.  All other exceptions are rethrown.
        /// </summary>
        /// <param name="ex">The exception to handle</param>
        /// <remarks>
        /// The exception must derive from CommunicationException otherwise it is rethrown.
        /// </remarks>
        public static void HandleNonSpecificWCFException(Exception ex, string title)
        {
            bool isWCFRelatedException = IsWCFRelatedException(ex);

            if (!isWCFRelatedException)
            {
                throw ex;
            }

            string message = Resources.WCFGeneralExceptionMessage;

            if (ex.GetType() == typeof(EndpointNotFoundException))
            {
                message = Resources.EndpointNotFoundExceptionMessage;
            }
            else if (ex.GetType() == typeof(SecurityAccessDeniedException))
            {
                message = Resources.WCFSecurityAccessDeniedExceptionMessage;
            }
            else if (ex.GetType() == typeof(MessageSecurityException) ||
                ex.GetType() == typeof(SecurityNegotiationException))
            {
                message = Resources.WCFGeneralSecurityExceptionMessage;
            }
            else if (ex.GetType() == typeof(TimeoutException))
            {
                message = Resources.TimeoutExceptionMessage;
            }
            else if (ex.GetType() == typeof(FaultException<string>))
            {
                var faultEx = ex as FaultException<string>;
                Debug.Assert(faultEx != null);
                message = faultEx.Detail;
            }

            IMessageBoxService messageBox = ServiceContainer.Instance.GetService<IMessageBoxService>();
            messageBox.Show(message, title, MessageBoxButton.OK, MessageBoxImage.Error);
        }

        #endregion
    }
}
